package com.hyacinth.cloudnote.modules.note.controller;

import com.hyacinth.cloudnote.common.dto.result.PageResultDTO;
import com.hyacinth.cloudnote.common.dto.result.ResultDTO;
import com.hyacinth.cloudnote.common.exception.ExceptionHolder;
import com.hyacinth.cloudnote.modules.note.converter.FavoriteConverter;
import com.hyacinth.cloudnote.modules.note.dto.FavoriteDTO;
import com.hyacinth.cloudnote.modules.note.model.Favorite;
import com.hyacinth.cloudnote.modules.note.repository.FavoriteRepository;
import com.hyacinth.cloudnote.modules.note.service.FavoriteService;
import io.micrometer.core.annotation.Timed;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.UUID;

import static com.hyacinth.cloudnote.modules.common.errorcode.NoteErrorCode.E1000000001;

/**
 * Favorite实体类对应的基础业务Controller
 */
@Slf4j
@RestController
@RequestMapping("/w/favorites")
@Api(tags = {"Favorite管理API" })
public class FavoriteController {

    @Autowired
    private FavoriteService favoriteService;
    @Autowired
    private FavoriteRepository favoriteRepository;
    @Autowired
    private FavoriteConverter favoriteConverter;


    /**
     * 获取分页数据
     *
     * @param pageable 分页+排序参数
     * @return 分页数据
     */
    @Timed
    @ApiOperation(value = "获取分页数据")
    @RequestMapping(value = "/s", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public PageResultDTO<FavoriteDTO> search(final Pageable pageable) {
        final Page<Favorite> models = this.favoriteRepository.findAll(pageable);
        return this.favoriteConverter.toResultDTO(models);
    }

    /**
     * 取得详细数据
     *
     * @param id 实体对象ID
     * @return 资源详细
     */
    @Timed
    @ApiOperation(value = "获取详细数据")
    @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
    public ResultDTO<FavoriteDTO> get(@PathVariable final UUID id) {
        final Favorite model = this.favoriteRepository.findById(id)
                    .orElseThrow(() -> ExceptionHolder.serviceException(E1000000001, "收藏夹" + id));
        return this.favoriteConverter.toResultDTO(model);
    }

    /**
     * 新建操作
     *
     * @param favoriteDTO 新建资源的DTO
     * @return 新建资源
     */
    @Timed
    @ApiOperation(value = "新建操作")
    @RequestMapping(method = RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE)
    public ResultDTO<FavoriteDTO> create(@RequestBody @Valid final FavoriteDTO favoriteDTO) {
        final Favorite model = this.favoriteConverter.toModel(favoriteDTO);
        this.favoriteService.save(model);
        if (log.isInfoEnabled()) {
            log.info("{} instance {} was created.", Favorite.class.getSimpleName(), model.getId());
        }
        return this.favoriteConverter.toResultDTO(model);
    }
    
    /**
     * 更新操作
     *
     * @param id 实体对象ID
     * @param favoriteDTO 更新资源的DTO
     * @return 更新后资源
     */
    @Timed
    @ApiOperation(value = "更新操作")
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces=MediaType.APPLICATION_JSON_VALUE)
    public ResultDTO<FavoriteDTO> update(@PathVariable final UUID id, @RequestBody @Valid final FavoriteDTO favoriteDTO) {
        favoriteDTO.setId(id);
        final Favorite model = this.favoriteConverter.toModel(favoriteDTO);
        this.favoriteService.save(model);
        if (log.isInfoEnabled()) {
            log.info("{} instance {} was updated.", Favorite.class.getSimpleName(), model.getId());
        }
        return this.favoriteConverter.toResultDTO(model);
    }

    /**
     * 删除操作
     *
     * @param id 实体对象ID
     * @return 操作结果
     */
    @Timed
    @ApiOperation(value = "删除操作")
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces=MediaType.APPLICATION_JSON_VALUE)
    public ResultDTO<Void> delete(@PathVariable final UUID id) {
        this.favoriteService.delete(id);
        if (log.isInfoEnabled()) {
            log.info("{} instance {} was deleted.", Favorite.class.getSimpleName(), id);
        }
        return ResultDTO.success();
    }
}
